package jpave.annotator;
/******************************************************
 * Creates small DBfasta files of only the hits -- for package distribution
 * demo_mix has both demo and demo_exp hits -- so works for all three
 * 
 * mkdir projects/tmpDB
 * from UniProt_MMMYYYY directory, cp asterick/asterick.fasta to ~user/pave_x.x/projects/tmpDB
 * this is the only way I know to make it work while executing from my MAC
 * change 'cari' to 'demo'
 */

import java.io.*;
import java.util.ArrayList;
import jpave.annotator.LineParser;

public class demoDBfasta {

	public static void main(String[] args) {

		ArrayList <String> orgFasta = new ArrayList <String> ();
		ArrayList <String> blastTab = new ArrayList <String> ();
		ArrayList <String> newFasta = new ArrayList <String> ();
		boolean plants = true;
		boolean bacteria = true;
		boolean fungi = true;
		boolean invert = true;
		boolean virus = false;
		boolean all = true;
		
		if (plants) {
			orgFasta.add("/tmpDB/uniprot_sprot_plants.fasta");
		    newFasta.add("/DBfasta/demo/plants/demo_sprot_plants.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPpla.tab"); 
		
			orgFasta.add("/tmpDB/uniprot_trembl_plants.fasta");
			newFasta.add("/DBfasta/demo/plants/demo_trembl_plants.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRpla.tab"); 
		}
		if (bacteria) {
			orgFasta.add("/tmpDB/uniprot_sprot_bacteria.fasta");
			newFasta.add("/DBfasta/demo/bacteria/demo_sprot_bacteria.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPbac.tab"); 
			
			orgFasta.add("/tmpDB/uniprot_trembl_bacteria.fasta");
			newFasta.add("/DBfasta/demo/bacteria/demo_trembl_bacteria.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRbac.tab"); 
		}
		if (fungi) {
			orgFasta.add("/tmpDB/uniprot_sprot_fungi.fasta");
			newFasta.add("/DBfasta/demo/fungi/demo_sprot_fungi.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPfun.tab"); 
			
			orgFasta.add("/tmpDB/uniprot_trembl_fungi.fasta");
			newFasta.add("/DBfasta/demo/fungi/demo_trembl_fungi.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRfun.tab"); 
		}
		if (invert) {
			orgFasta.add("/tmpDB/uniprot_sprot_invertebrates.fasta");
			newFasta.add("/DBfasta/demo/invertebrates/demo_sprot_invertebrates.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPinv.tab"); 
			
			orgFasta.add("/tmpDB/uniprot_trembl_invertebrates.fasta");
			newFasta.add("/DBfasta/demo/invertebrates/demo_trembl_invertebrates.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRinv.tab"); 
		}
		if (virus) {
			orgFasta.add("/tmpDB/uniprot_sprot_viruses.fasta");
			newFasta.add("/DBfasta/demo/viruses/demo_sprot_viruses.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPvir.tab"); 
			
			orgFasta.add("/tmpDB/uniprot_trembl_viruses.fasta");
			newFasta.add("/DBfasta/demo/viruses/demo_trembl_viruses.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRvir.tab"); 
		}
		if (all) {
			orgFasta.add("/tmpDB/uniprot_sprot_pfvib.fasta");
			newFasta.add("/DBfasta/demo/all/demo_sprot_pfvib.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_SPall.tab"); 
			
			orgFasta.add("/tmpDB/uniprot_trembl_pfvib.fasta");
			newFasta.add("/DBfasta/demo/all/demo_trembl_pfvib.fasta");
			blastTab.add("/demo_mix/uniblasts/cari_mix_TRall.tab"); 
		}
		// String outpath = "/Volumes/cari/mac_pave/projects";
		String outpath = "./projects";
		File path = new File(outpath);
 	    if ( !(path.exists()) && path.isDirectory() ) 
 	    		System.err.println("*** " + path + " does not exist");
		
		for (int i=0; i < orgFasta.size(); i++) {
			ArrayList <String> geneSet = new ArrayList <String> (); 
		
			getGeneSet(outpath + blastTab.get(i), geneSet);
			System.err.println("Gene set " + geneSet.size());

			createFasta(outpath + orgFasta.get(i), outpath + newFasta.get(i), geneSet);
			System.err.println("done");
		}
	}
	
	static void getGeneSet(String blastFile, ArrayList <String> geneSet) 
	{
		int nHitNum=0;
		String gene="";
		System.err.println("Reading " + blastFile);
		File path = new File(blastFile);
 	    if ( !(path.exists()) ) {
 	    		System.err.println(blastFile + " does not exist");
 	    }
	    	try {
	    		BufferedReader reader = new BufferedReader ( new FileReader ( blastFile ) );
	    		String line;
	    		LineParser lp = new LineParser ();
	    		
	    		while ((line = reader.readLine()) != null) {
	    			if ( line.length() == 0 || line.charAt(0) == '#' ) continue;  			
		    		String[] tokens = line.split("\t");
		    		if (tokens == null || tokens.length < 11) continue;
		    		lp.parseLine(line);
			    	gene = lp.getHitID();
			    	
			    	if (!geneSet.contains(gene)) geneSet.add(gene);
			    	
			    	nHitNum++;
			    if (nHitNum % 100000 == 0 )                 
			        System.err.print("   read " + nHitNum + " genes " + geneSet.size() + "\r");	  
	    		}
	    		reader.close();
		}
	    catch ( Throwable err ) {
	    		err.printStackTrace();
	    		System.exit(-1);
	    }
	}

	static void createFasta(String realFile, String outFile, ArrayList <String> geneSet) 
	{
		int nHitNum=0;
		int nAddNum=0;
		String gene="";
		LineParser lp = new LineParser();
		boolean addHit=false;
		System.err.println("Reading " + realFile);
		System.err.println("Writing " + outFile);
		
	    	try {
	    		PrintWriter pWriter = new PrintWriter(new FileWriter(outFile));
	    		BufferedReader reader = new BufferedReader ( new FileReader ( realFile ) );
	    		String line;
	        
			while((line = reader.readLine()) != null) {	        
				if (line.charAt(0) == '#' || line.charAt(0) == ' ' || line.length() < 5) 
					continue;
				
				if (line.charAt(0) != '>') {
					if (addHit) 
						pWriter.println(line);
					continue;
				}
						
				if (!lp.parseFasta(line)) {
		        		System.err.println("Cannot parse line: " + line);
		        		System.exit(-1);
				}
				gene = lp.getHitID();
					
				if (geneSet.contains(gene)) {
					addHit = true;
					pWriter.println(line);
					nAddNum++;
				}
				else addHit = false;
				
				nHitNum++;
				if (nHitNum % 100000 == 0 ) 	                
			         System.err.print(" Read " + nHitNum + "  Write " + nAddNum + " ....\r");					
			}
			System.err.print(" Read " + nHitNum + "  Write " + nAddNum + "        ");		
	    		reader.close();
	    		pWriter.close();
		}
	    catch ( Throwable err ) {
	    		err.printStackTrace();
	    		System.exit(-1);
	    }
	}
}
